package com.ys.everydaynews.base

import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableList.OnListChangedCallback
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView

abstract class BaseBindingAdapter<M, B : ViewDataBinding>(items: ObservableArrayList<M>) :
    RecyclerView.Adapter<BaseBindingAdapter.BaseBindingViewHolder>() {
    private var items: ObservableArrayList<M> = items
    private var itemsChangeCallback: ListChangedCallback = ListChangedCallback()


    open fun getItems(): ObservableArrayList<M>? {
        return items
    }

    protected var mOnItemClickListener: OnItemClickListener<*>? = null

    open fun setOnItemClickListener(mOnItemClickListener: OnItemClickListener<M>?) {
        this.mOnItemClickListener = mOnItemClickListener
    }

    interface OnItemClickListener<M> {
        fun onItemClick(bean: Any?, position: Int)
    }


    /**
     * 重写id可以使刷新不闪烁
     */
    override fun getItemId(position: Int): Long {

        var position = position
        if (position < 0) {
            position = 0
        }
        if (position >= items.size) {
            Log.e("越界了，position：$position", ",mList.size():" + items.size)
            return System.currentTimeMillis()
        }
        return items[position].hashCode().toLong()
    }


    override fun getItemCount(): Int {
        return items.size
    }

    override fun getItemViewType(position: Int): Int {
        return super.getItemViewType(position)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseBindingViewHolder {
        val binding: B =
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                getLayoutResId(),
                parent,
                false
            )
        return BaseBindingViewHolder(binding.root)
    }

    override fun onBindViewHolder(holder: BaseBindingViewHolder, position: Int) {
        try {
            val bean = items[position]
            val binding: B? = DataBindingUtil.getBinding(holder.itemView)
            if (binding != null) {
                if (mOnItemClickListener != null) {
                    binding.root.setOnClickListener {
                        mOnItemClickListener!!.onItemClick(
                            bean,
                            holder.adapterPosition
                        )
                    }
                }
            }
            onBindItem(binding, bean, position)
            //this.onBindItem(binding, this.items.get(position));
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        items.addOnListChangedCallback(itemsChangeCallback)
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        items.removeOnListChangedCallback(itemsChangeCallback)
    }


    protected fun resetItems(newItems: ObservableArrayList<M>?) {
        items = newItems!!
    }


    protected abstract fun getLayoutResId(): Int


    protected abstract fun onBindItem(binding: B?, bean: M, position: Int)
//    protected abstract void onBindItem(B binding, M bean);

    /**
     * 额外监听数据变化，这样就可以直接更新数据，
     * 而不用每次都调用notifyDataSetChanged()等方式更新数据
     * 只对插入和移除做了监听处理，其他方式没有处理

     */
    private inner class ListChangedCallback : OnListChangedCallback<ObservableArrayList<M>>() {
        override fun onChanged(sender: ObservableArrayList<M>?) {
            Log.i("onChanged:", sender.toString())
        }

        override fun onItemRangeChanged(
            sender: ObservableArrayList<M>?,
            positionStart: Int,
            itemCount: Int
        ) {
            Log.i("onItemRangeChanged:", "$positionStart--$itemCount,$sender")
        }

        override fun onItemRangeInserted(
            sender: ObservableArrayList<M>?,
            positionStart: Int,
            itemCount: Int
        ) {
//            Log.i("onItemRangeInserted:" , positionStart + "--" + itemCount + "," + newItems.toString());
            notifyItemRangeInserted(positionStart, itemCount)
        }

        override fun onItemRangeMoved(
            sender: ObservableArrayList<M>?,
            fromPosition: Int,
            toPosition: Int,
            itemCount: Int
        ) {
            Log.i("onItemRangeMoved:", "$fromPosition--$toPosition,itemCount:$itemCount,$sender")
        }

        override fun onItemRangeRemoved(
            sender: ObservableArrayList<M>?,
            positionStart: Int,
            itemCount: Int
        ) {
            Log.i("onItemRangeRemoved:", "$positionStart--$itemCount,$sender")
            notifyItemRangeRemoved(positionStart, itemCount)
        }
    }

    class BaseBindingViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView!!)
}